﻿using System;
using System.Xml;
using System.Collections.Generic;
using System.Text;
using System.Runtime.InteropServices;
using SIMcSDK;


namespace SIMc
{
    public class XMLConfig
    {
        XmlDocument xmlDoc;
        string path;

        public XMLConfig(string appPath)
        {
            this.path = appPath + "config.xml";
            xmlDoc = new XmlDocument();
            try
            {
                xmlDoc.Load(path);
            }
            catch (Exception e)
            {
                createUltraConfig();
            }
        }

        public void createConfig()
        {
            XmlDeclaration xmlDeclaration = xmlDoc.CreateXmlDeclaration("1.0", "utf-8", "no");

            XmlElement rootNode = xmlDoc.CreateElement("Config");
            xmlDoc.InsertBefore(xmlDeclaration, xmlDoc.DocumentElement);
            xmlDoc.AppendChild(rootNode);
        }

        public void createUltraConfig()
        {
            XmlDeclaration xmlDeclaration = xmlDoc.CreateXmlDeclaration("1.0", "utf-8", "no");

            XmlElement rootNode = xmlDoc.CreateElement("Config");
            xmlDoc.InsertBefore(xmlDeclaration, xmlDoc.DocumentElement);
            xmlDoc.AppendChild(rootNode);

            for (int i = 1; i < 7; i++)
                addProfile(i);
        }

        public bool addProfile(int profileID)
        {
            XmlElement profileElem = xmlDoc.CreateElement("profile");
            xmlDoc.DocumentElement.AppendChild(profileElem);
            XmlAttribute IDAttr = xmlDoc.CreateAttribute("ID");
            IDAttr.Value = profileID.ToString();
            profileElem.Attributes.Append(IDAttr);

            XmlElement groupElem = xmlDoc.CreateElement("codec");
            groupElem.InnerText = "PCMU";
            profileElem.AppendChild(groupElem);

            XmlElement portElem = xmlDoc.CreateElement("port");
            portElem.InnerText = "5060";
            profileElem.AppendChild(portElem);

            XmlElement vadElem = xmlDoc.CreateElement("VAD");
            vadElem.InnerText = "true";
            profileElem.AppendChild(vadElem);

            XmlElement ecElem = xmlDoc.CreateElement("ec_tail");
            ecElem.InnerText = "200";
            profileElem.AppendChild(ecElem);

            XmlElement clockRateElem = xmlDoc.CreateElement("clock_rate");
            clockRateElem.InnerText = "8000";
            profileElem.AppendChild(clockRateElem);

            XmlElement qualityElem = xmlDoc.CreateElement("quality");
            qualityElem.InnerText = "1";
            profileElem.AppendChild(qualityElem);

            XmlElement ptimeElem = xmlDoc.CreateElement("ptime");
            ptimeElem.InnerText = "200";
            profileElem.AppendChild(ptimeElem);
            
            XmlElement iceElem = xmlDoc.CreateElement("ice");
            iceElem.InnerText = "true";
            profileElem.AppendChild(clockRateElem);

            XmlElement expireElem = xmlDoc.CreateElement("expire");
            expireElem.InnerText = "3600";
            profileElem.AppendChild(expireElem);

            XmlElement autoElem = xmlDoc.CreateElement("autologin");
            autoElem.InnerText = "false";
            profileElem.AppendChild(autoElem);

            XmlElement stunElem = xmlDoc.CreateElement("stun");
            stunElem.InnerText = "";
            profileElem.AppendChild(stunElem);

            XmlElement usestunElem = xmlDoc.CreateElement("usestun");
            usestunElem.InnerText = "false";
            profileElem.AppendChild(usestunElem);

            XmlElement xcapElem = xmlDoc.CreateElement("xcap");
            xcapElem.InnerText = "";
            profileElem.AppendChild(xcapElem);

            xmlDoc.Save(path);

            return true;
        }

        public struct Config {
            public string codec;
            public int port;
            public bool VAD;
            public int ec_tail;
            public int clock_rate;
            public int quality;
            public int ptime;
            public bool ice;
            public string pjsipfile;
            public int expire;
            public bool autologin;
            public string stun;
            public bool useStun;
            public string xcap;
        }

        public ConfigControl.SIMcConfigStruct constructPjsipConf(Config config){

            ConfigControl.SIMcConfigStruct pjsipConf = new ConfigControl.SIMcConfigStruct();

            pjsipConf.clock_rate = config.clock_rate;
            pjsipConf.ECTail = config.ec_tail;
            pjsipConf.expires = config.expire;
            pjsipConf.iceEnabled = config.ice;
            pjsipConf.listenPort = config.port;
            pjsipConf.pjsiplogpath = config.pjsipfile;
            pjsipConf.ptime = config.ptime;
            pjsipConf.quality = config.quality;
            pjsipConf.stun = config.stun;
            pjsipConf.useStun = config.useStun;
            pjsipConf.VADEnabled = config.VAD;

            return pjsipConf;
        }

        internal bool updateProfile(Config config, int profileID)
        {
            foreach (XmlNode lNode in xmlDoc.DocumentElement.ChildNodes)
            {
                if ((int.Parse(lNode.Attributes.Item(0).Value)).Equals(profileID))
                {
                    foreach (XmlNode gNode in lNode.ChildNodes)
                    {
                        switch (gNode.Name)
                        {
                            case "codec":
                                gNode.InnerText = config.codec;
                                break;
                            case "port":
                                gNode.InnerText = config.port.ToString();
                                break;
                            case "VAD":
                                gNode.InnerText = config.VAD.ToString();
                                break;
                            case "ec_tail":
                                gNode.InnerText = config.ec_tail.ToString();
                                break;
                            case "clock_rate":
                                gNode.InnerText = config.clock_rate.ToString();
                                break;
                            case "quality":
                                gNode.InnerText = config.quality.ToString();
                                break;
                            case "ptime":
                                gNode.InnerText = config.ptime.ToString();
                                break;
                            case "ice":
                                gNode.InnerText = config.ice.ToString();
                                break;
                            case "expire":
                                gNode.InnerText = config.expire.ToString();
                                break;
                            case "autologin":
                                gNode.InnerText = config.autologin.ToString();
                                break;
                            case "stun":
                                gNode.InnerText = config.stun.ToString();
                                break;
                            case "usestun":
                                gNode.InnerText = config.useStun.ToString();
                                break;
                            case "xcap":
                                gNode.InnerText = config.xcap;
                                break;
                        }
                    }
                    break;
                }
            }
            xmlDoc.Save(path);
            return true;
        }

        internal Config getConfig(int profileID){
            Config config = new Config();
            foreach (XmlNode lNode in xmlDoc.DocumentElement.ChildNodes)
            {
                if ((int.Parse(lNode.Attributes.Item(0).Value)).Equals(profileID))
                {
                    foreach (XmlNode gNode in lNode.ChildNodes)
                    {
                        switch (gNode.Name)
                        {
                            case "codec":
                                config.codec= gNode.InnerText;
                                break;
                            case "port":
                                config.port=int.Parse(gNode.InnerText);
                                break;
                            case "VAD":
                                config.VAD = bool.Parse(gNode.InnerText);
                                break;
                            case "ec_tail":
                                config.ec_tail = int.Parse(gNode.InnerText);
                                break;
                            case "clock_rate":
                                config.clock_rate = int.Parse(gNode.InnerText);
                                break;
                            case "quality":
                                config.quality = int.Parse(gNode.InnerText);
                                break;
                            case "ptime":
                                config.ptime = int.Parse(gNode.InnerText);
                                break;
                            case "ice":
                                config.ice = bool.Parse(gNode.InnerText);
                                break;
                            case "expire":
                                config.expire = int.Parse(gNode.InnerText);
                                break;
                            case "autologin":
                                config.autologin = bool.Parse(gNode.InnerText);
                                break;
                            case "stun":
                                config.stun = gNode.InnerText;
                                break;
                            case "usestun":
                                config.useStun = bool.Parse(gNode.InnerText);
                                break;
                            case "xcap":
                                config.xcap = gNode.InnerText;
                                break;
                        }
                    }
                    break;
                }
            }
            xmlDoc.Save(path);
            return config;
        }

        public void fillSettingsForm(SettingsForm settingsForm, Config config)
        {
            //acc1
            int index=0;
            foreach (string obsah in settingsForm.CB_codec.Items) {
                if (obsah.Equals(config.codec)) {
                    settingsForm.CB_codec.SelectedIndex = index;
                }
                index++;
            }
            settingsForm.CB_codec.Text = config.codec;
            settingsForm.TB_port.Text = config.port.ToString();
            settingsForm.CB_VAD.Checked = config.VAD;
            settingsForm.TB_ecTail.Text = config.ec_tail.ToString();
            settingsForm.TB_clockRate.Text = config.clock_rate.ToString();
            settingsForm.CB_quality.SelectedIndex = (config.quality-1);
            settingsForm.TB_ptime.Text = config.ptime.ToString();
            settingsForm.TB_expire.Text = config.expire.ToString();
            //settingsForm.CB_autologin.Checked = config.autologin;
            settingsForm.TB_stun.Text = config.stun;
            settingsForm.CB_useSTUN.Checked = config.useStun;
            settingsForm.TB_xcap.Text = config.xcap;

        }
  
    }
}
